package main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

/**
 * Panel gracza
 * @author Maciej Krawczyk
 */
@SuppressWarnings("serial")
public class PlayerPanel extends JPanel implements PropertyChangeListener {

	/**Etykiety wyswietlajace karty gracza*/
	private JLabel card1, card2, card3, card4;
	/**Labele wyswietlajace pozostale informacje panelu gracza (stawka na stole, aktualna runda, komunikat, rola gracza, jego stawka i zetony)*/
	private JLabel tip, blindLabel, stakeLabel, chipsLabel, potLabel, roundLabel;
	/**Pola tekstowe do wpisywana wysokosci podbijanej stawki*/
	private JTextField raiseField, betField;
	/**Boxy do zaznaczania, ktore karty gracz zyczy sobie wymienic*/
	private JCheckBox checkbox1, checkbox2, checkbox3, checkbox4;
	/**Przyciski funkcyjne w panelu gracza*/
	private JButton betButton, raiseButton, allInButton, checkButton, callButton, foldButton, skipButton, exchangeButton;
	/**Czcionki*/
	private Font font, cardFont, tipFont;
	/**Modyfikator zarzadcy rozkladu panelu*/
	private GridBagConstraints c;
	/**Tablica przechowujaca karty*/
	private JLabel[] aCards;
	/**Instancja klasy z danymi gry*/
	private GuiData gd;
	/**Numer identyfikacyjny gracza*/
	private int id;
	
	/**
	 * Konstruktor panelu gracza
	 * @param guiData obiekt z danymi gry
	 */
	public PlayerPanel(GuiData guiData) {
		gd = guiData;
		this.setLayout(new GridBagLayout());
		this.setBackground(new Color(21, 134, 183));
		this.setOpaque(true);
		font = new Font(Font.SERIF, Font.PLAIN, 23);
		cardFont = new Font(Font.SERIF, Font.PLAIN, 32);
		tipFont = new Font(Font.SERIF, Font.PLAIN, 30);
		c = new GridBagConstraints();
		c.insets = new Insets(10, 15, 10, 15);
		
		card1 = new JLabel("");
		card1.setFont(cardFont);
//		card1.setBackground(new Color(21, 134, 183));
		card1.setBackground(Color.WHITE);
		card1.setHorizontalAlignment(SwingConstants.CENTER);
		card1.setPreferredSize(new Dimension (60, 70));
		c.gridx = 0;
		c.gridy = 0;
		this.add(card1, c);
		
		card2 = new JLabel("");
		card2.setFont(cardFont);
//		card2.setBackground(new Color(21, 134, 183));
		card2.setBackground(Color.WHITE);
		card2.setHorizontalAlignment(SwingConstants.CENTER);
		card2.setPreferredSize(new Dimension (60, 70));
		c.gridx = 1;
		c.anchor = GridBagConstraints.CENTER;
		this.add(card2, c);
		
		card3 = new JLabel("");
		card3.setFont(cardFont);
//		card3.setBackground(new Color(21, 134, 183));
		card3.setBackground(Color.WHITE);
		card3.setHorizontalAlignment(SwingConstants.CENTER);
		card3.setPreferredSize(new Dimension (60, 70));
		c.gridx = 2;
		c.ipadx = 0;
		this.add(card3, c);
		
		card4 = new JLabel("");
		card4.setFont(cardFont);
//		card4.setBackground(new Color(21, 134, 183));
		card4.setBackground(Color.WHITE);
		card4.setHorizontalAlignment(SwingConstants.CENTER);
		card4.setPreferredSize(new Dimension (60, 70));
		c.gridx = 3;
		this.add(card4, c);
		
		aCards = new JLabel[4];
		aCards[0] = card1;
		aCards[1] = card2;
		aCards[2] = card3;
		aCards[3] = card4;
		
		c.anchor = GridBagConstraints.CENTER;
		c.fill = GridBagConstraints.BOTH;
		c.ipady = 0;
		
		checkbox1 = new JCheckBox();
		checkbox1.setBackground(new Color(21, 134, 183));
		checkbox1.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridy++;
		c.gridx = 0;
		c.ipadx = 70;
		this.add(checkbox1, c);
		
		checkbox2 = new JCheckBox();
		checkbox2.setBackground(new Color(21, 134, 183));
		checkbox2.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 1;
		c.ipadx = 110;
		this.add(checkbox2, c);
		
		checkbox3 = new JCheckBox();
		checkbox3.setBackground(new Color(21, 134, 183));
		checkbox3.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 2;
		c.ipadx = 10;
		this.add(checkbox3, c);
		
		checkbox4 = new JCheckBox();
		checkbox4.setBackground(new Color(21, 134, 183));
		checkbox4.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 3;
		c.ipadx = 75;
		this.add(checkbox4, c);
		
		exchangeButton = new JButton("Exchange");
		exchangeButton.setFont(font);
		exchangeButton.addActionListener(gd);
		c.gridy++;
		c.gridx = 0;
		c.gridwidth = 2;
		this.add(exchangeButton, c);
		
		skipButton = new JButton("Skip");
		skipButton.setFont(font);
		skipButton.addActionListener(gd);
		c.gridx = 2;
		c.gridwidth = 2;
		this.add(skipButton, c);
		
		roundLabel = new JLabel("");
		roundLabel.setFont(font);
		roundLabel.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 0;
		c.gridwidth = 1;
		c.gridy++;
		this.add(roundLabel, c);
		
		tip = new JLabel("");
		tip.setFont(tipFont);
		tip.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridwidth = 3;
		c.gridx = 1;
		this.add(tip, c);
		
		checkButton = new JButton("Check");
		checkButton.setFont(font);
		checkButton.addActionListener(gd);
		c.gridx = 0;
		c.gridy++;
		c.gridwidth = 1;
		this.add(checkButton, c);
		
		betField = new JTextField(1);
		betField.setFont(font);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.anchor = GridBagConstraints.PAGE_END;
		c.insets = new Insets(10, 15, 0, 15);
		c.gridx = 1;
		this.add(betField, c);
		
		raiseField = new JTextField();
		raiseField.setFont(font);
		c.gridx = 2;
		this.add(raiseField, c);
		
		foldButton = new JButton("Fold");
		foldButton.setFont(font);
		foldButton.addActionListener(gd);
		c.insets = new Insets(10, 15, 10, 15);
		c.gridx = 3;
		c.fill = GridBagConstraints.BOTH;
		this.add(foldButton, c);
		
		callButton = new JButton("Call");
		callButton.setFont(font);
		callButton.addActionListener(gd);
		c.gridx = 0;
		c.gridy++;
		this.add(callButton, c);
		
		betButton = new JButton("Bet");
		betButton.setFont(font);
		betButton.addActionListener(gd);
		c.fill = GridBagConstraints.BOTH;
		c.gridx = 1;
		this.add(betButton, c);
		
		raiseButton = new JButton("Raise");
		raiseButton.setFont(font);
		raiseButton.addActionListener(gd);
		c.gridx = 2;
		this.add(raiseButton, c);
		
		allInButton = new JButton("All-In");
		allInButton.setFont(font);
		allInButton.addActionListener(gd);
		c.insets = new Insets(10, 15, 10, 15);
		c.gridx = 3;
		this.add(allInButton, c);
		
		potLabel = new JLabel("POT: 0");
		potLabel.setFont(font);
		c.gridx = 0;
		c.gridy++;
		potLabel.setHorizontalAlignment(SwingConstants.CENTER);
		this.add(potLabel, c);
		
		stakeLabel = new JLabel("Stake: 0");
		stakeLabel.setFont(font);
		stakeLabel.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 1;
		this.add(stakeLabel, c);
		
		chipsLabel = new JLabel("Chips: ");
		chipsLabel.setFont(font);
		chipsLabel.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 2;
		this.add(chipsLabel, c);
				
		blindLabel = new JLabel("");
		blindLabel.setFont(font);
		blindLabel.setHorizontalAlignment(SwingConstants.CENTER);
		c.gridx = 3;
		this.add(blindLabel, c);
	}

	/**
	 * Metoda umozliwa sprzezenie pomiedzy danymi z gry, a GUI (zmiana w danych = zmiana w GUI)
	 * @see java.beans.PropertyChangeEvent
	 */
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		switch (evt.getPropertyName()) {
		case "setBlind":
			setBlind(evt.getNewValue().toString());
			break;
		case "setChips":
			setChips((int) evt.getNewValue());
			break;
		case "setTip":
			setTip(evt.getNewValue().toString());
			break;
		case "setCards":
			setCards(evt.getNewValue().toString());
			break;
		case "setStake":
			setStake((int) evt.getNewValue());
		case "setPot":
			setPot((int) evt.getNewValue());
			break;
		default:
			System.out.println("Nieznana komenda gracza");
			break;
		}		
	}
	
	/**
	 * Metoda ustawia karty gracza
	 * @param cards karty gracza
	 */
	private void setCards(String cards) {
		for(int i = 0; i < 7; i += 2) {		
			String rank = cards.substring(i, i + 1);
			if(rank.equals("0"))
				rank = "10";
			String suit = cards.substring(i + 1, i + 2);
			switch (suit) {
			case "h":
				aCards[i / 2].setText(rank + "\u2665");
				aCards[i / 2].setForeground(new Color(206, 26, 44));
				aCards[i / 2].setOpaque(true);
				break;
			case "d":
				aCards[i / 2].setText(rank + "\u2666");
				aCards[i / 2].setForeground(new Color(206, 26, 44));
				aCards[i / 2].setOpaque(true);
				break;
			case "s":
				aCards[i / 2].setText(rank + "\u2660");
				aCards[i / 2].setForeground(Color.BLACK);
				aCards[i / 2].setOpaque(true);
				break;
			case "c":
				aCards[i / 2].setText(rank + "\u2663");
				aCards[i / 2].setForeground(Color.BLACK);
				aCards[i / 2].setOpaque(true);
				break;
			default:
				System.out.println("nie rozpoznaje koloru karty");
				break;
			}			
		}
	}

	/**
	 * Akcesor zwracajacy numer gracza
	 * @return numer gracza
	 */
	public int getId() {
		return id;
	}
	
	/**
	 * Metoda ustawia laczna stawke na stole
	 * @param pot wysokosc lacznej stawki na stole
	 */
	public void setPot(int pot) {
		potLabel.setText("POT: " + pot);
	}
	
	/**
	 * Metoda ustawia zetony gracza
	 * @param chips liczba zetonow
	 */
	public void setChips(int chips) {
		chipsLabel.setText("Chips: " + chips);		
	}

	/**
	 * Metoda ustawia role gracza (blind)
	 * @param blind rola gracza
	 */
	public void setBlind(String blind) {
		blindLabel.setText(blind);
	}
	
	/**
	 * Metoda ustawia komunikat/porade w panelu gracza
	 * @param tip komunikat/porada
	 */
	public void setTip(String tip) {
		this.tip.setText(tip);
	}

	/**
	 * Metoda ustawia stawke gracza
	 * @param s wysokosc stawki
	 */
	public void setStake(int s) {
		stakeLabel.setText("Stake: " + s);
	}
	
	/**
	 * Mutator ustawiajacy numer gracza
	 * @param i numer gracza
	 */
	public void setId(int i) {
		this.id = i;
	}
	
	/**
	 * Akcesor informujacy o stanie box1
	 * @return informacja czy box zostal odznaczony
	 */
	public boolean isCheckbox1() {
		return checkbox1.isSelected();
	}
	
	/**
	 * Akcesor informujacy o stanie box2
	 * @return informacja czy box zostal odznaczony
	 */
	public boolean isCheckbox2() {
		return checkbox2.isSelected();
	}
	
	/**
	 * Akcesor informujacy o stanie box3
	 * @return informacja czy box zostal odznaczony
	 */
	public boolean isCheckbox3() {
		return checkbox3.isSelected();
	}
	
	/**
	 * Akcesor informujacy o stanie box4
	 * @return informacja czy box zostal odznaczony
	 */
	public boolean isCheckbox4() {
		return checkbox4.isSelected();
	}
	
	/**Mutator odznaczajacy wszystkie boxy*/
	public void clearCheckboxes() {
		checkbox1.setSelected(false);
		checkbox2.setSelected(false);
		checkbox3.setSelected(false);
		checkbox4.setSelected(false);	
	}
	
	/**
	 * Metoda steruje dostepem do komponentow w panelu gracza
	 * @param k wariant dostepu
	 */
	public void setAccesToPanel(int k) {
		if (k == 0) {
			checkbox1.setEnabled(false);
			checkbox2.setEnabled(false);
			checkbox3.setEnabled(false);
			checkbox4.setEnabled(false);
			exchangeButton.setEnabled(false);
			skipButton.setEnabled(false);
			checkButton.setEnabled(false);
			callButton.setEnabled(false);
			foldButton.setEnabled(false);
			allInButton.setEnabled(false);
			betField.setEditable(false);
			raiseField.setEditable(false);
			betButton.setEnabled(false);
			raiseButton.setEnabled(false);
		}
		else if(k == 1) {
			checkbox1.setEnabled(true);
			checkbox2.setEnabled(true);
			checkbox3.setEnabled(true);
			checkbox4.setEnabled(true);
			skipButton.setEnabled(true);
			exchangeButton.setEnabled(true);
			checkButton.setEnabled(false);
			callButton.setEnabled(false);
			foldButton.setEnabled(false);
			allInButton.setEnabled(false);
			betField.setEditable(false);
			raiseField.setEditable(false);
			betButton.setEnabled(false);
			raiseButton.setEnabled(false);
		}
		else
			System.out.println("PlayerPanel blad dostepu do komponentow");
	}
	
	/**
	 * Akcesor zwracajacy wysokosc stawki, o ktora podbija gracz
	 * @return wysokosc stawki
	 */
	public String getRaise() {
		String raise = raiseField.getText();
		clearFields();
		return raise;
	}
	
	/**
	 * Akcesor zwracajacy wysokosc stawki, o ktora podbija gracz
	 * @return wysokosc stawki
	 */
	public String getBet() {
		String bet = betField.getText();
		clearFields();
		return bet;
	}
	
	/**Metoda czysci pola tekstowe w panelu gracza*/
	public void clearFields() {
		raiseField.setText("");
		betField.setText("");
	}
	
	/**Metoda decyduje o dostepie do przycisku "Check"*/
	public void setAToCheck(boolean decision) {
		checkButton.setEnabled(decision);
	}
	
	/**Metoda decyduje o dostepie do przycisku "Call"*/
	public void setAToCall(boolean decision) {
		callButton.setEnabled(decision);
	}
	
	/**Metoda decyduje o dostepie do przycisku "Bet"*/
	public void setAToBet(boolean decision) {
		betButton.setEnabled(decision);
	}
	
	/**Metoda decyduje o dostepie do przycisku "Raise"*/
	public void setAToRaise(boolean decision) {
		raiseButton.setEnabled(decision);
	}
	
	/**Metoda decyduje o dostepie do przycisku "All-In"*/
	public void setAToAllIn(boolean decision) {
		allInButton.setEnabled(decision);
	}
	
	/**Metoda decyduje o dostepie do przycisku "Fold"*/
	public void setAToFold(boolean decision) {
		foldButton.setEnabled(decision);
	}
	
	/**Metoda decyduje o dostepie do pola tekstowego "Raise"*/
	public void setAToRaiseField(boolean decision) {
		raiseField.setEditable(decision);
	}
	
	/**Metoda decyduje o dostepie do pola tekstowego "Bet"*/
	public void setAToBetField(boolean decision) {
		betField.setEditable(decision);
	}
	
	/**
	 * Metoda ustawia numer rundy na etykiecie
	 * @param text numer rundy
	 */
	public void setRoundLabel(String text) {
		roundLabel.setText(text);
	}
}
